﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Interop;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;

namespace TDTool
{
    /// <summary>
    /// BlurWindow.xaml 的交互逻辑
    /// </summary>
    public partial class BlurWindow : Window
    {
        public BlurWindow()
        {
            InitializeComponent();
        }


        protected override void OnSourceInitialized(EventArgs e)
        {
            if (Environment.OSVersion.Version.Major >= 6)
            {
                base.OnSourceInitialized(e);
                GlassHelper.ExtendGlassFrame(this, new Thickness(-1));
            }
        }

        private void mButton_Click(object sender, RoutedEventArgs e)
        {
            AdornerLayer.GetAdornerLayer(mGrid).Add(new SimpleCircleAdorner(mGrid));
        }
    }


    [StructLayout(LayoutKind.Sequential)]
    public struct MARGINS
    {
        public MARGINS(Thickness t)
        {
            Left = (int)t.Left;
            Right = (int)t.Right;
            Top = (int)t.Top;
            Bottom = (int)t.Bottom;
        }
        public int Left;
        public int Right;
        public int Top;
        public int Bottom;
    }

    public class GlassHelper
    {
        [DllImport("dwmapi.dll", PreserveSig = false)]
        static extern void DwmExtendFrameIntoClientArea(
            IntPtr hWnd, ref MARGINS pMarInset);
        [DllImport("dwmapi.dll", PreserveSig = false)]
        static extern bool DwmIsCompositionEnabled();

        public static bool ExtendGlassFrame(Window window, Thickness margin)
        {
            if (!DwmIsCompositionEnabled())
                return false;

            IntPtr hwnd = new WindowInteropHelper(window).Handle;
            if (hwnd == IntPtr.Zero)
                throw new InvalidOperationException(
                "The Window must be shown before extending glass.");

            // Set the background to transparent from both the WPF and Win32 perspectives
            window.Background = Brushes.Transparent;
            HwndSource.FromHwnd(hwnd).CompositionTarget.BackgroundColor = Colors.Transparent;

            MARGINS margins = new MARGINS(margin);
            DwmExtendFrameIntoClientArea(hwnd, ref margins);
            return true;
        }
    }




    //============================================================================
    static class Win10BlurHelper
    {
        [DllImport("user32.dll")]
        internal static extern int SetWindowCompositionAttribute(IntPtr hwnd, ref WindowCompositionAttributeData data);

        internal enum AccentState
        {
            ACCENT_DISABLED = 0,
            ACCENT_ENABLE_GRADIENT = 1,
            ACCENT_ENABLE_TRANSPARENTGRADIENT = 2,
            ACCENT_ENABLE_BLURBEHIND = 3,
            ACCENT_INVALID_STATE = 4
        }

        [StructLayout(LayoutKind.Sequential)]
        internal struct AccentPolicy
        {
            public AccentState AccentState;
            public int AccentFlags;
            public int GradientColor;
            public int AnimationId;
        }

        [StructLayout(LayoutKind.Sequential)]
        internal struct WindowCompositionAttributeData
        {
            public WindowCompositionAttribute Attribute;
            public IntPtr Data;
            public int SizeOfData;
        }

        internal enum WindowCompositionAttribute
        {
            // ...
            WCA_ACCENT_POLICY = 19
            // ...
        }

        public static void EnableBlur(Window _window)
        {
            var WindowPtr = new WindowInteropHelper(_window).Handle;

            var accent = new AccentPolicy()
            {
                AccentState = AccentState.ACCENT_ENABLE_BLURBEHIND,
                AccentFlags = 0x20 | 0x40 | 0x80 | 0x100,
                //GradientColor = 0x000000FF,
                //AnimationId = 
            };
            var accentStructSize = Marshal.SizeOf(accent);

            var accentPtr = Marshal.AllocHGlobal(accentStructSize);
            Marshal.StructureToPtr(accent, accentPtr, false);

            var data = new WindowCompositionAttributeData()
            {
                Attribute = WindowCompositionAttribute.WCA_ACCENT_POLICY,
                SizeOfData = accentStructSize,
                Data = accentPtr
            };
            SetWindowCompositionAttribute(WindowPtr, ref data);

            Marshal.FreeHGlobal(accentPtr);
        }
    }

    static class Win7BlurHelper
    {
        [DllImport("dwmapi.dll")]
        static extern void DwmEnableBlurBehindWindow(IntPtr hwnd, ref DWM_BLURBEHIND blurBehind);

        struct DWM_BLURBEHIND
        {
            public uint dwFlags;
            public bool fEnable;
            public IntPtr hRgnBlur;
            public bool fTransitionOnMaximized;
        }

        public static void EnableAeroGlass(Window _window)
        {
            var WindowPtr = new WindowInteropHelper(_window).Handle;

            var Blur = new DWM_BLURBEHIND()
            {
                dwFlags = 0x00000001 | 0x00000002,
                fEnable = true
            };

            DwmEnableBlurBehindWindow(WindowPtr, ref Blur);
        }
    }

    
    //============================================================================
    public class SimpleCircleAdorner : Adorner {
	    // Be sure to call the base class constructor.
	    public SimpleCircleAdorner(UIElement adornedElement)
		    : base(adornedElement) {
	    }
 
	    // A way to implement an adorner's rendering behavior is to override the OnRender
	    // method, which is called by the layout system as part of a rendering pass.
	    protected override void OnRender(DrawingContext drawingContext) {
		    Rect adornedElementRect = new Rect(this.AdornedElement.DesiredSize);
 
		    // Some arbitrary drawing implements.
		    SolidColorBrush renderBrush = new SolidColorBrush(Colors.Green);
		    renderBrush.Opacity = 0.2;
		    Pen renderPen = new Pen(new SolidColorBrush(Colors.Navy), 1.5);
		    double renderRadius = 5.0;
 
		    // Draw a circle at each corner.
		    drawingContext.DrawEllipse(renderBrush, renderPen,
				    adornedElementRect.TopLeft, renderRadius, renderRadius);
		    drawingContext.DrawEllipse(renderBrush, renderPen,
				    adornedElementRect.TopRight, renderRadius, renderRadius);
		    drawingContext.DrawEllipse(renderBrush, renderPen,
				    adornedElementRect.BottomLeft, renderRadius, renderRadius);
		    drawingContext.DrawEllipse(renderBrush, renderPen,
				    adornedElementRect.BottomRight, renderRadius, renderRadius);
	    }
    }
}
